package com.itheima.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.dao.EmployeeDao;
import com.itheima.reggie.entity.Employee;
import com.itheima.reggie.entity.dto.LoginDto;
import com.itheima.reggie.service.EmployeeService;
import com.itheima.reggie.utils.ThreadLocalUtil;
import com.itheima.reggie.web.R;
import com.itheima.reggie.web.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.servlet.http.HttpSession;
import javax.websocket.Session;
import java.time.LocalDateTime;

/**
 * 员工业务层实现类
 *
 * @Author Vsunks.v
 * @Date 2022/8/10 8:58
 * @Blog blog.sunxiaowei.net/996.mba
 * @Description: 员工业务层实现类，继承ServiceImpl<EmployeeDao, Employee>，并且实现接口EmployeeService
 */
@Slf4j
@Service
public class EmployeeServiceImpl extends ServiceImpl<EmployeeDao, Employee> implements EmployeeService {

    @Autowired
    EmployeeDao employeeDao;

    /**
     * 保存用户，并校验用户名是否重复
     *
     * @param employee 要保存的员工信息
     * @return 是否保存成功
     */
    @Override
    public boolean saveWithDataInit(Employee employee) {
        log.info("EmployeeService中线程名称：{}",Thread.currentThread().getName());
        // 设置密码并加密
        employee.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));

        // 设置默认状态为1
        employee.setStatus(1);

        // 设置新建/更新时间/人
        // employee.setCreateTime(LocalDateTime.now());
        // employee.setUpdateTime(LocalDateTime.now());

        // Long employeeId = (Long) session.getAttribute("employee");
        // employee.setCreateUser(ThreadLocalUtil.getCurrentId());
        // employee.setUpdateUser(ThreadLocalUtil.getCurrentId());

        checkDuplicateName(employee);

        // 保存
        // employeeDao.insert(employee);
        // 返回结果
        return this.save(employee);
    }


    /**
     * 登录，并根据参数校验结果，给出相应提示提示
     *
     * @param loginDto 登录参数封装对象
     * @return 含有Employee对象
     */
    @Override
    public Employee login(LoginDto loginDto) {

        // 1. 加密提交的`password`，得到密文
        String pwd = DigestUtils.md5DigestAsHex(loginDto.getPassword().getBytes());

        // 2. 判断员工是否存在
        // 2.1 构建查询条件对象
        LambdaQueryWrapper<Employee> lqw = Wrappers.lambdaQuery(Employee.class);

        // 2.2 设置查询条件
        String username = loginDto.getUsername();
        lqw.eq(StringUtils.isNotBlank(username), Employee::getUsername, username);
        // 2.3 查询
        Employee employee = getOne(lqw);
        if (employee == null) {
            throw new BusinessException("用户名不存在，你再想想？");
        }

        // 3. 判断密码是否正确
        if (!employee.getPassword().equals(pwd)) {
            throw new BusinessException("密码错了，你再想想？");
        }


        // 4. 判断员工是否被禁用
        if (employee.getStatus().equals(0)) {
            throw new BusinessException("都离职了，还回来干啥！？");
        }

        // 6.1 响应实体脱敏处理并返回
        employee.setPassword(null);
        employee.setIdNumber(null);


        return employee;
    }

    /**
     * 分页查询
     *
     * @param pageNum  页码
     * @param pageSize 页面大小
     * @param name     查询条件，可以为null
     * @return 分页对象
     */
    @Override
    public Page page(Integer pageNum, Integer pageSize, String name) {
        // 构建查询条件对象，并设置查询条件
        LambdaQueryWrapper<Employee> lqw = Wrappers.lambdaQuery(Employee.class);
        lqw.like(StringUtils.isNotBlank(name), Employee::getName, name)
                .or()
                .like(StringUtils.isNotBlank(name), Employee::getUsername, name)
                .orderByDesc(Employee::getUpdateTime);

        // 创建分页对象，并设置分页参数
        Page<Employee> page = new Page<>(pageNum, pageSize);

        // 查询并相应结果
        return page(page, lqw);

    }


    /**
     * 根据id按需更新，并检查用户名是否重复
     *
     * @param employee 要更新的信息
     * @return 更新是否成功
     */
    @Override
    public boolean updateById(Employee employee) {
        // 1.检查用户名是否重复
        // 1.1 根据用户名查询
        checkDuplicateName(employee);

        // 2. 更新用户
        return employeeDao.updateById(employee) > 0;
    }


    /**
     * 检查用户名是否重复
     *
     * @param employee
     */
    private void checkDuplicateName(Employee employee) {
        // 根据用户名查询
        LambdaQueryWrapper<Employee> lqw = Wrappers.lambdaQuery(Employee.class);
        String username = employee.getUsername();
        // lqw.eq(StringUtils.isNotBlank(username), Employee::getUsername, username);
        lqw.eq(Employee::getUsername, username);
        Employee employeeInDb = employeeDao.selectOne(lqw);


        // 判断对象是否为空，不为空则表示用户名重复了，需要抛异常
        if (employeeInDb != null) {
            // 避免查询到自己之后产生的bug
            if (!employeeInDb.getId().equals(employee.getId())) {
                throw new BusinessException("用户名：" + username + "重复");
            }
        }
    }
}
